import mapboxgl from 'mapbox-gl'

export interface CoordinatePickerOptions {
  onChange?: (lnglat: string) => void;
  container?: HTMLElement; // 容器元素
}

export default class CoordinatePicker {
  private map: mapboxgl.Map
  private marker: mapboxgl.Marker | null = null
  private enabled: boolean = false
  private options: CoordinatePickerOptions
  private controlContainer: HTMLElement
  private coordinateInput: HTMLInputElement
  private toggleButton: HTMLInputElement
  private defaultMarker: mapboxgl.Marker | null = null

  constructor(map: mapboxgl.Map, options: CoordinatePickerOptions = {}) {
    this.map = map
    this.options = options
    this.controlContainer = this.createControl()
    this.coordinateInput = this.controlContainer.querySelector('input[type="text"]')!
    this.toggleButton = this.controlContainer.querySelector('input[type="checkbox"]')!
    
    if (options.container) {
      options.container.appendChild(this.controlContainer)
    } else {
      this.map.getContainer().appendChild(this.controlContainer)
    }

    this.initializeEvents()
  }

  private createMarker(lngLat: [number, number], type?:string): mapboxgl.Marker {
    if (type === 'popup') {
      const el = document.createElement('div')
      el.style.cssText = `
        padding: 5px;
        background-color: rgba(255, 255, 255, 0.5);
        border-radius: 5px; 
        border: 1px solid #1890ff;
        color: #1890ff;
        box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1);
        font-size: 14px;
      `
      return new mapboxgl.Marker({
        element: el,
        anchor: 'left',
        offset: [6, -20]
      }).setLngLat(lngLat).addTo(this.map)
    }

    return new mapboxgl.Marker({
      anchor: 'center',
      offset: [6, -20]
    }).setLngLat(lngLat).addTo(this.map)
    
  }

  private createControl(): HTMLElement {
    const container = document.createElement('div')
    container.style.cssText = `
      display: flex;
      align-items: center;
      gap: 10px;
      position: absolute;
      top: 10px;
      right: 10px;
      z-index: 9;
      padding: 10px;
      background-color: rgba(255, 255, 255, 0.8);
    `

    container.innerHTML = `
      <input type="checkbox" id="coordinate-toggle" />
      <label for="coordinate-toggle">坐标拾取器</label>
      <input type="text" placeholder="经度,纬度" style="
        width: 150px;
        padding: 5px;
        border: 1px solid #ccc;
        border-radius: 5px;
      " />
      <button class="locate-btn">定位</button>
      <button class="clear-btn">清除</button>
    `

    // 绑定事件
    const toggle = container.querySelector('input[type="checkbox"]') as HTMLInputElement
    toggle.addEventListener('change', (e) => {
      if (toggle.checked) {
        this.enable()
      } else {
        this.disable()
      }
    })

    const locateBtn = container.querySelector('.locate-btn') as HTMLButtonElement
    locateBtn.addEventListener('click', () => {
      const input = container.querySelector('input[type="text"]') as HTMLInputElement
      if (input.value) {
        this.setLocation(input.value)
      }
    })

    const clearBtn = container.querySelector('.clear-btn') as HTMLButtonElement
    clearBtn.addEventListener('click', () => {
      const input = container.querySelector('input[type="text"]') as HTMLInputElement
      input.value = ''
      this.defaultMarker?.remove()
      this.defaultMarker = null
    })

    return container
  }

  private initializeEvents(): void {
    this.map.on('mousemove', (e) => {
      if (this.enabled && this.marker) {
        const lngLat = [e.lngLat.lng, e.lngLat.lat]
        this.marker.setLngLat(lngLat)
        this.marker.getElement().innerHTML = `<div>${lngLat[0].toFixed(6)}, ${lngLat[1].toFixed(6)}</div>`
      }
    })

    this.map.on('click', (e) => {
      if (this.enabled) {
        const lngLat = `${e.lngLat.lng.toFixed(6)},${e.lngLat.lat.toFixed(6)}`
        this.coordinateInput.value = lngLat
        this.options.onChange?.(lngLat)
        if (this.defaultMarker) {
          this.defaultMarker.setLngLat([e.lngLat.lng, e.lngLat.lat])
        }else{
          this.defaultMarker = this.createMarker([e.lngLat.lng, e.lngLat.lat]) 
        }
      }
    })
  }

  public enable(): void {
    this.enabled = true
    if (!this.marker) {
      this.marker = this.createMarker([0, 0], 'popup')
    }
  }

  public disable(): void {
    this.enabled = false
    this.marker?.remove()
    this.marker = null
  }

  public setLocation(lngLat: string): void {
    const coordinates = lngLat.split(',').map(Number)
    if (coordinates.length === 2 && !isNaN(coordinates[0]) && !isNaN(coordinates[1])) {
      this.map.flyTo({
        center: coordinates as [number, number],
        zoom: 13,
        speed: 5,
        curve: 1,
        easing: (t) => t,
        essential: true
      })
    }
  }

  public getValue(): string {
    return this.coordinateInput.value
  }

  public setValue(value: string): void {
    this.coordinateInput.value = value
  }

  public destroy(): void {
    this.disable()
    this.controlContainer.remove()
  }
}
